#ifndef THREAD_THREADPOOL_H
#define THREAD_THREADPOOL_H

#include "utility/Noncopyable.h"
#include "utility/func.h"

#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <string>
#include <vector>

class Thread;

class ThreadPool
{

public:
    ThreadPool(std::size_t maxSize = 0, std::string name = "ThreadPool");
    ~ThreadPool();

    const std::string &name() const { return _name; };

    void set_init_task(TrivialFunc task);

    void run(TrivialFunc task);
    void start(std::size_t threadCount);
    void stop();
    std::size_t task_size() {
        const std::lock_guard guard{_mutex};
        return _tasks.size();
    }

private:
    NONCOPYABLE(ThreadPool);

    bool _is_full() const;
     void _thread_func();
    void _run_in_thread();
   

    std::deque<TrivialFunc> _tasks;
    std::condition_variable _notEmpty;
    std::condition_variable _notFull;
    std::mutex _mutex;
    const std::string _name;
    TrivialFunc _initTask;
    std::vector<std::unique_ptr<Thread>> _threads;
    const std::size_t _maxSize;
    bool _running;
};



#endif